/* *

 * 
 */
package Control;

import Acquaintance.IASearchType;
import BPlusTreeIndex.BTree;
import BPlusTreeIndex.Key;
import DALFactory.IDataSearchLogMapper;
import Entity.EHouse;
import KDTreeIndex.DataImport;
import KDTreeIndex.KDTree;

import java.util.*;

/**
 * 索引类 实现对缓存中对象的索引维护和搜索 采用B+树数据结构实现
 * 
 * @author Administrator
 */
public class CIndex {

	private CCache cache;
	private BTree PriceTree;
	private BTree AreaTree;
	private KDTree TypeTree;
	private HashMap<String, ArrayList<Integer>> PremiseTree;
	private HashMap<String, ArrayList<Integer>> LocationTree;
	private HashMap<Integer, ArrayList<Integer>> FloorTree;
	private IDataSearchLogMapper iDSLM;
	private static CIndex index;
	private int Oder = 3;

	/**
	 * CIndex类的构造方法私有
	 */
	private CIndex() {
		cache = CCache.getCache();
		initIndex(cache.getHouseMap());
	}

	/**
	 * 初始化houseList列表
	 */
	private void initIndex(HashMap map) {
		TreeMap<Integer, ArrayList<Integer>> PriceTreeMap = new TreeMap<Integer, ArrayList<Integer>>();
		TreeMap<Integer, ArrayList<Integer>> AreaTreeMap = new TreeMap<Integer, ArrayList<Integer>>();
		HashMap<KDTreeIndex.Key,ArrayList<Integer>> TypeData=new HashMap<KDTreeIndex.Key,ArrayList<Integer>>();
		
		LocationTree = new HashMap<String, ArrayList<Integer>>();
		FloorTree = new HashMap<Integer, ArrayList<Integer>>();
		
		iDSLM = CCache.getCache().getDALFactory().CreatDataSearchLogMapper();

		PremiseTree = new HashMap<String, ArrayList<Integer>>();
		Iterator iterator = map.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<Integer, EHouse> entry = (Map.Entry) iterator.next();
			EHouse house = entry.getValue();
			int HID = house.getHID();
			int price = house.getHousePrice();
			int Floor = house.getFloor();

			String Location = house.getLocation();

			float Area = house.getArea();
			String Type = house.getType();
			String Premise = house.getPremise();

			KDTreeIndex.Key key=new KDTreeIndex.Key(3);
			key.setKey(DataImport.getKey(Type));
			if(TypeData.containsKey(key))
			{
				TypeData.get(key).add(house.getHID());
			}
			else
			{						
				ArrayList<Integer> HIDs=new ArrayList<Integer>();
				HIDs.add(house.getHID());
				TypeData.put(key, HIDs);
			}	
			
			if (PriceTreeMap.containsKey(price)) {
				PriceTreeMap.get(price).add(HID);
			} else {

				ArrayList<Integer> HIDList = new ArrayList<Integer>();
				HIDList.add(HID);
				PriceTreeMap.put(price, HIDList);
			}
			if (FloorTree.containsKey(Floor)) {
				FloorTree.get(Floor).add(HID);
			} else {
				ArrayList<Integer> HIDList = new ArrayList<Integer>();
				HIDList.add(HID);
				FloorTree.put(Floor, HIDList);
			}

			if (AreaTreeMap.containsKey((int) Area)) {
				AreaTreeMap.get((int) Area).add(HID);
			} else {
				ArrayList<Integer> HIDList = new ArrayList<Integer>();
				HIDList.add(HID);
				AreaTreeMap.put((int) Area, HIDList);
			}

			if (PremiseTree.containsKey(Premise)) {
				PremiseTree.get(Premise).add(HID);
			} else {
				ArrayList<Integer> HIDList = new ArrayList<Integer>();
				HIDList.add(HID);
				PremiseTree.put(Premise, HIDList);
			}

			if (LocationTree.containsKey(Location)) {
				LocationTree.get(Location).add(HID);
			} else {
				ArrayList<Integer> HIDList = new ArrayList<Integer>();
				HIDList.add(HID);
				LocationTree.put(Location, HIDList);
			}

		}
		AreaTree = new BTree(AreaTreeMap, Oder);
		PriceTree = new BTree(PriceTreeMap, Oder);
		TypeTree = new KDTree(3);		
		TypeTree.buildTree(TypeData);
	}

	/**
	 * 重建索引
	 */
	public void rebuildIndex() {
		initIndex(cache.getHouseMap());
	}

	/**
	 * 实例化一个线程安全的CIndex单例
	 */
	private static synchronized void syncInit() {
		if (index == null) {
			index = new CIndex();
		}
	}

	/**
	 * 获得CIndex单例
	 * 
	 * @return
	 */
	public static CIndex getIndex() {
		syncInit();
		return index;
	}

	/**
	 * 搜索功能
	 * 
	 * @param keyWords
	 *            关键字
	 * @return 搜索结果<HID>
	 */
	public ArrayList<Integer> search(String keyWords) {
		boolean mat = keyWords.matches("\\d+");
		ArrayList<Integer> result;
		if (mat) {
			int Number = Integer.parseInt(keyWords);
			Key<Integer> key = new Key<Integer>(Number);
			if (Number < 15) {
				iDSLM.InsertSearch_Log(keyWords, "Floor", new Date(System.currentTimeMillis()));
				result= index.FloorTree.get(Number);
				result.add(IASearchType.FLOOR);
				return result;
			} else if (Number < 200) {
				iDSLM.InsertSearch_Log(keyWords, "Area", new Date(System.currentTimeMillis()));
				 result= index.AreaTree.Search(key);
				 result.add(IASearchType.AREA);
				 return result;
			} else {
				iDSLM.InsertSearch_Log(keyWords, "Price", new Date(System.currentTimeMillis()));
				result= index.PriceTree.Search(key);
				 result.add(IASearchType.PRICE);
				 return result;
			}

		}  else if (DataImport.check(keyWords)) {
			
			
			KDTreeIndex.Key key = new KDTreeIndex.Key(3);
			key.setKey(DataImport.getKey(keyWords));
			iDSLM.InsertSearch_Log(keyWords, "Type", new Date(System.currentTimeMillis()));
			result= index.TypeTree.Search(key);
			 result.add(IASearchType.TYPE);
			 return result;
		} else if (index.PremiseTree.containsKey(keyWords)) {
			iDSLM.InsertSearch_Log(keyWords, "Premise", new Date(System.currentTimeMillis()));
			result=index.PremiseTree.get(keyWords);
			 result.add(IASearchType.PRMISE);
			return result;
		} else if (index.LocationTree.containsKey(keyWords)) {
			iDSLM.InsertSearch_Log(keyWords, "Location", new Date(System.currentTimeMillis()));
			result=index.LocationTree.get(keyWords);
			result.add(IASearchType.LOCATION);
			return result;
		}
		return null;
	}
	

}
